package weiconsole;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.StringTokenizer;

import java.util.Date;
import java.util.Properties;
import java.util.ArrayList;

import weibo4j.Weibo;
import weibo4j.model.WeiboException;
import weiconsole.ui.NativeUI;

public class Main {

	static String propmt = "";
	static Properties mainProps = new Properties();
	static String userPropsPath = "";
	static Properties userProps = new Properties();
	
	static Weibo weibo;
	static UserManager umanager;
	static TimelineManager tmmanager;
	static Main main = new Main();
	
	static ArrayList<Module> modules = new ArrayList<Module>();
	
	static NativeUI nativeUI = new NativeUI();
	
	public static void main(String [] args) throws WeiboException, IOException{
		mainProps.load(main.getClass().getClassLoader().getResourceAsStream("weiconsole.properties"));
		nativeUI.cleanScreen();
		
		propmt = mainProps.getProperty("weiconsole.propmt") + " ";
		
		/* get user information */
		userPropsPath = System.getProperty("user.home") + File.separatorChar + ".weiconuser";
		try {
			File userFile = new File(userPropsPath);
			if (!userFile.exists()) {
				try {
					userFile.createNewFile();
				} catch (Exception e) {
					error("failed to create user profile" + e.toString());
				}
			}
			
			/* load */
			FileInputStream fin = new FileInputStream(Main.userPropsPath); 
			userProps.load(fin); 
			fin.close();
			
		} catch (Exception e) {
			Main.error("failed to load user config file");
		}
		
		/* register kernel module */
		Module kernel = new Module("weiconsole.Main", main);
		kernel.addFunction("quit");
		registerModule(kernel);
		
		umanager = new UserManager();
		tmmanager = new TimelineManager();
		
		/* try to login */
		System.out.println("trying to login...");
		umanager.tryToLogin();
		
		main.run();
	}
	
	public static void registerModule(Module mod) {
		modules.add(mod);
	}
	
	public static Module lookUpModule(String funcName) {
		for (int i = 0; i < modules.size(); i++) {
			if (modules.get(i).lookUpFunctionName(funcName)) return modules.get(i);
		}
		
		return null;
	}
	
	public void run() {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		while (true) {
			//updateStatusBar();
			String methodName = "";
			try {
				System.out.print(propmt);
				System.out.flush();
				String command = br.readLine();
				
				if (command.equals("")) continue;

				StringTokenizer st = new StringTokenizer(command);
				methodName = st.nextToken();
			
				int argc = st.countTokens();
				int i;
				String[] args = new String[argc];
				for (i = 0; i < argc; i++) {
					args[i] = st.nextToken();
				}
				Class[] cargs = new Class[1];
				cargs[0] = args.getClass();
				Module mod = lookUpModule(methodName);
				if (null == mod) throw new NoSuchMethodException();
				Method method = Class.forName(mod.getClassName()).getMethod(methodName, cargs);
				Object[] oargs = new Object[1];
				oargs[0] = args;
				method.invoke(mod.getObj(), oargs);
			} catch (NoSuchMethodException e) {
				error("invalid command `" + methodName + "'");
			} catch (Exception e) {
				error("failed to execute command(" + e.toString() + ")");
			}
		}
	}

	public static String[] tokenize(String str) {
		StringTokenizer st = new StringTokenizer(str);
	
		int argc = st.countTokens();
		int i;
		String[] args = new String[argc];
		for (i = 0; i < argc; i++) {
			args[i] = st.nextToken();
		}
		
		return args;
	}
	
	public void updateStatusBar() {
		nativeUI.saveCursorPos();
		nativeUI.moveCursor(0, 0);
		nativeUI.setBackground(NativeUI.CL_BLUE);
		nativeUI.setForeground(NativeUI.CL_WHITE);
		
		for (int i = 1; i < nativeUI.scrCol(); i++) System.out.print(' ');
		nativeUI.moveCursor(nativeUI.scrCol() - "WeiConsole".length(), 0);
		System.out.print("WeiConsole");
		
		nativeUI.moveCursor(0, 0);
		if (!isLoggedIn()) {
			System.out.print("not logged in");
		} else {
			System.out.print(umanager.getCurrentUser().getName());
			nativeUI.moveCursor(0, 2);
			for (int i = 1; i < nativeUI.scrCol(); i++) System.out.print(' ');
			nativeUI.moveCursor(0, 2);
			System.out.print("friends: " + umanager.getCurrentUser().getFriendsCount());
			System.out.print("  followers: " + umanager.getCurrentUser().getFollowersCount());
			System.out.print("  statuses: " + umanager.getCurrentUser().getStatusesCount());
		}
		
		nativeUI.setBackground(NativeUI.CL_NORMAL);
		nativeUI.restoreCursorPos();
	}
	
	public static void error(String msg) {
		System.out.flush();
		nativeUI.setForeground(NativeUI.CL_RED);
		System.err.println("error: " + msg);
		nativeUI.setForeground(NativeUI.CL_NORMAL);
		System.err.flush();
	}
	
	public static boolean checkLoggedIn() {
		if (!isLoggedIn()) {
			Main.error("you must login to do that");
			return false;
		}
		return true;
	}
	
	public void quit(String args[]) {
		System.exit(0);
	}
	
	public static boolean isLoggedIn() {
		return umanager.loggedIn;
	}
	
	public static String printDate(Date date) {
		SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd kk:mm:ss");
		return f.format(date);
	}
}
